﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using DnPakExplorer.Forms;
using AndBurn.DDSReader;

namespace DnPakExplorer.Controls {
	public partial class EquipmentPanelCtrl : ItemSlotPanelCtrl {

        const string XML_PATH = ".\\Data\\euipemnt.xml";

		SlotGroup mHead;
		SlotGroup mBody;
		SlotGroup mLeg;
		SlotGroup mGlove;
		SlotGroup mBoots;
		SlotGroup mWeapon;
		SlotGroup mWeapon2;
		SlotGroup mRing1;
		SlotGroup mRing2;
		SlotGroup mEaring;
		SlotGroup mNecklace;
		SlotGroup mSource;

		public class SlotGroup : MyView {

			private List<ItemSlotBox> mItemIcons = new List<ItemSlotBox>();
			public int TextOffsetX = 0;
			public int TextOffsetY = 5;

			public ItemSlotBox Slot { get; private set; }

			public SlotGroup(int slotId) {
				Size = new System.Drawing.Size(200, 64);
				Slot = new ItemSlotBox();
				Slot.TargetSlotId = slotId;
				Slot.Bounds = new Rectangle(0, 0, 64, 64);
				Slot.OnSlotChanged += Slot_OnSlotChanged;
			}

			void Slot_OnSlotChanged(IItemSlot newSlot, IItemSlot oldSlot) {
				if (oldSlot != null) {
					oldSlot.OnItemChanged -= OnItemChanged;
				}
				if (newSlot != null) {
					newSlot.OnItemChanged += OnItemChanged;
				}

				OnItemChanged();
			}

			void OnItemChanged() {
				mItemIcons.ForEach(slot => slot.TargetSlot.OnItemChanged -= djs_OnItemChanged);
				mItemIcons.Clear();
				if (Slot.Item != null) {
					if (Slot.Item.slotsType>0) {
						PartImage backImage = new PartImage();
						backImage = new PartImage();
						backImage.ImageSource = new DDSImage((byte[])Properties.Resources.uit_item_slot04).BitmapImage;
						backImage.SourceRect = new Rectangle(3, 2, 50, 50);
						Point startPoint = new Point(Slot.Bounds.Right, 22);
						foreach (DragonJewelSlot djs in Slot.Item.AppliedSlotsList) {
							ItemSlotBox slot = new ItemSlotBox();
							slot.Bounds = new Rectangle(startPoint, new Size(30, 30));
							slot.TargetSlot = djs;
							slot.Background = backImage;
							slot.Background.DestRect = slot.ClientRect;
							slot.ItemDestRect = slot.ClientRect;
							slot.TypeImage = new PartImage();
							slot.TypeImage.ImageSource = Util.GetJewelTypeImage(djs.DragonJewelSlotType);
							slot.TypeImage.SourceRect = new Rectangle(0, 0, 50, 50);
							slot.TypeImage.DestRect = slot.ClientRect;
							mItemIcons.Add(slot);

							djs.OnItemChanged += djs_OnItemChanged;

							startPoint.X += slot.Bounds.Width;
						}
					}
				}
			}

			void djs_OnItemChanged(IItemSlot slot, IUserItem oldItem) {
				Parent.Invalidate();
			}

			void OnItemChanged(IItemSlot slot, IUserItem oldItem) {
				OnItemChanged();
			}

			public override void OnDraw(Graphics g) {
				base.OnDraw(g);
				Point offset = Slot.Position;
				g.TranslateTransform(offset.X, offset.Y);
				Slot.OnDraw(g);
				g.TranslateTransform(-offset.X, -offset.Y);
				//g.DrawRectangle(Pens.OrangeRed, ClientRect);

				if (Slot.Item != null) {
					Font font = new Font("微软雅黑", 8.5f, GraphicsUnit.Point);
					StringFormat sf = new StringFormat();
					Rectangle rect = new Rectangle(
						Slot.Bounds.Right+TextOffsetX,
						TextOffsetY,
						Bounds.Width-Slot.Bounds.Right-TextOffsetX,
						Slot.Bounds.Height-TextOffsetY);
					SolidBrush bursh = new SolidBrush(Util.GetRankColor(Slot.Item.rank));
					g.DrawString(Slot.Item.name, font, bursh, rect, sf);
				}
				foreach (ItemSlotBox ii in mItemIcons) {
					offset = ii.Position;
					g.TranslateTransform(offset.X, offset.Y);
					ii.OnDraw(g);
					g.TranslateTransform(-offset.X, -offset.Y);
				}
			}

			public override void OnMouseMove(System.Windows.Forms.MouseEventArgs e) {
				IUserItem item = null;
				if (Slot.ItemDestRect.Contains(e.Location)) {
					item = Slot.Item;
				} else {
					foreach (ItemSlotBox ii in mItemIcons) {
						if (ii.Bounds.Contains(e.Location)) {
							item = ii.Item;
							break;
						}
					}
				}
				if (item != null) {
					this.Capture = true;
					InfoOverlayForm.ShowItem(item);
				} else {
					InfoOverlayForm.HideItem();
					this.Capture = false;
				}
			}

			public override void OnMouseUp(MouseEventArgs e) {
				if (Slot.Bounds.Contains(e.Location)) {
					if (e.Button == System.Windows.Forms.MouseButtons.Right) {
						if (System.Windows.Forms.Control.ModifierKeys == Keys.Shift) {
							if (Slot.Item != null) {
								InfoOverlayForm.HideItem();
								new ItemEdtorForm(Slot.Item).ShowDialog(Parent);
							}
						} else {
							IUserItem item = Slot.TargetSlot.Unequip();
							if (item != null) {
								DnPlayerUtil.CurrentCharacter.BagPanel.AddItem(item);
							}
						}
					}
				} else {
					foreach (ItemSlotBox ii in mItemIcons) {
						if (ii.Bounds.Contains(e.Location)) {
							if (e.Button == System.Windows.Forms.MouseButtons.Right) {
								IUserItem item = ii.TargetSlot.Unequip();
								if (item != null) {
									DnPlayerUtil.CurrentCharacter.BagPanel.AddItem(item);
								}
								break;
							} else if (e.Button == System.Windows.Forms.MouseButtons.Left) {
								BagForm bag = new BagForm(DnPlayerUtil.CurrentCharacter);
								bag.SetUseTarget(new DragonJewelSelector(ii.TargetSlot));
								bag.ShowDialog();
							}
						}
					}
				}
			}

			public override void OnMouseLeave() {
				InfoOverlayForm.HideItem();
				this.Capture = false;
			}

			class DragonJewelSelector : IItemUseTarget {
				IItemSlot mSlot;
				public DragonJewelSelector(IItemSlot slot) {
					mSlot = slot;
				}
				public void UseItem(BagPanel bag, IUserItem item) {
					if (item.exchangType == ItemType.DragonJewel &&　mSlot.CanEquip(item)) {
						IUserItem[] items = mSlot.Equip(item);
						bag.RemoveItem(item);
						foreach (IUserItem i in items) {
							bag.AddItem(i);
						}
					}
				}
			}
		}

		public EquipmentPanelCtrl() {
			InitializeComponent();

			AddSlot(mHead = new SlotGroup(EquipmentPanel.IS_HEAD));
			AddSlot(mBody = new SlotGroup(EquipmentPanel.IS_BODY));
			AddSlot(mLeg = new SlotGroup(EquipmentPanel.IS_LEG));
			AddSlot(mGlove = new SlotGroup(EquipmentPanel.IS_HAND));
			AddSlot(mBoots = new SlotGroup(EquipmentPanel.IS_BOOTS));
			AddSlot(mSource = new SlotGroup(EquipmentPanel.IS_SOURCE));
			AddSlot(mWeapon = new SlotGroup(EquipmentPanel.IS_MAIN_WEAPON));
			AddSlot(mWeapon2 = new SlotGroup(EquipmentPanel.IS_SECONDARY_WEAPON));
			AddSlot(mRing1 = new SlotGroup(EquipmentPanel.IS_RING1));
			AddSlot(mRing2 = new SlotGroup(EquipmentPanel.IS_RING2));
			AddSlot(mEaring = new SlotGroup(EquipmentPanel.IS_EARRING));
			AddSlot(mNecklace = new SlotGroup(EquipmentPanel.IS_NECKLACE));

			double scale = 0.8f;

			mSlotBackground.ImageSource = ItemSlotPanelCtrl.mSlotBackground.ImageSource;
			mSlotBackground.SourceRect = new Rectangle(0, 0, 69, 69);
			mSlotBackground.DestRect = new Rectangle(0, 0, (int)Math.Round(69*scale), (int)Math.Round(69*scale));

			this.ForAllView<SlotGroup>(group => {
				group.Slot.Background = mSlotBackground;
				group.Slot.SeletedImage = mSelectedImage;
				group.Slot.ItemDestRect = new Rectangle((int)Math.Round(10*scale), (int)Math.Round(10*scale), (int)Math.Round(50*scale), (int)Math.Round(50*scale));
				group.Slot.TypeImage = GetTypeImage(group.Slot.TargetSlotId, new Rectangle((int)Math.Round(10*scale), (int)Math.Round(10*scale), (int)Math.Round(50*scale), (int)Math.Round(50*scale)));
			});

			

			//////////////////////////////////////////////////////////////////////////////////////




			if (File.Exists(XML_PATH)) {
				XmlDocument doc = new XmlDocument();
				doc.Load(XML_PATH);
				XmlNodeList list = doc.SelectNodes("/Root/Slot");
				int i = 0;
				this.ForEachView<SlotGroup>(slot => {
					if (i<list.Count) {
						XmlAttributeCollection attrs = list[i++].Attributes;
						slot.Bounds = new Rectangle(
							int.Parse(attrs.GetNamedItem("x").InnerText),
							int.Parse(attrs.GetNamedItem("y").InnerText),
							slot.Bounds.Width,
							slot.Bounds.Height
							);
						return false;
					} else
						return true;
				});
			}

		}

		public override void Init(Character character) {
			base.Init(character);
			this.ForAllView<SlotGroup>(group => {
				if (group.Slot != null) {
					group.Slot.TargetSlot = (character.EquipmentPanel as EquipmentPanel).GetSlot<IItemSlot>(group.Slot.TargetSlotId);
					group.Slot.TargetSlot.Tag = group.Slot;
					group.Slot.TargetSlot.OnItemChanged += OnItemSlotChanged;
				}
			});
		}

		public void AddSlot(SlotGroup group) {
			AddView(group);
			AddSlot(group.Slot);
		}

		public new void AddSlot(ItemSlotBox slot) {
			if (!ContainsView(slot)) {
				if (Character != null) {
					slot.TargetSlot = (Character.EquipmentPanel as EquipmentPanel).GetSlot<IItemSlot>(slot.TargetSlotId);
					slot.TargetSlot.Tag = slot;
					slot.TargetSlot.OnItemChanged += OnItemSlotChanged;
				}
			}

		}


		private void OnItemSlotChanged(IItemSlot slot, IUserItem oldItem) {
			if (IsDisposed) {
				Cleanup();
				return;
			}
			Invalidate();
		}


		protected override void SaveLayout() {
			XmlDocument doc = new XmlDocument();
			doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", ""));
			XmlElement rootNode = doc.CreateElement("Root");
			doc.AppendChild(rootNode);
			this.ForAllView<SlotGroup>(slot => {
				XmlElement slotNode = doc.CreateElement("Slot");
				slotNode.SetAttribute("x", slot.Bounds.X.ToString());
				slotNode.SetAttribute("y", slot.Bounds.Y.ToString());
				rootNode.AppendChild(slotNode);
			});
			doc.Save(XML_PATH);
		}
	}
}
